import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import { PagesKey } from '@/global/constant'
import {
  getPageList,
  reqPageAdd,
  reqPageBatchDelete,
  reqPageDelete,
  reqPageEdit
} from '@/service/module/main/page-common'
import { IThunkState } from '@/global/type'
import { encryptData } from '@/utils/encrypt'
import { reqRefreshLexicon } from '@/service/module/main/system/sensitive'

interface IPagination {
  current: number
  size: number
  total: number
}

interface IGetListConfig {
  pageKey: PagesKey
  params: any
}

interface IPageCommonState {
  pageList: any[]
  pagination: IPagination
  isLoading: boolean
  searchConfig: IGetListConfig
  propIds: number[]
  currentRecord: any
}

/* 数据区 */
const initialState: IPageCommonState = {
  pageList: [],
  // 储存分页的信息，多处使用
  pagination: {
    current: 1,
    size: 10,
    total: 0
  },
  isLoading: false,
  // 储存当前页面的搜索参数，多处使用
  searchConfig: {
    pageKey: PagesKey.UserList,
    params: {}
  },
  // 储存页面选中的表格项
  propIds: [],
  // 补充：如果再让我重新写一遍项目，我会再把主要信息都存在这里，比如 当前行的数据
  currentRecord: {}
}

/** 异步action **/
export const fetchPageListAction = createAsyncThunk(
  'fetch/pageList',
  async (config: IGetListConfig, { dispatch }) => {
    const { pageKey, params } = config
    dispatch(changeIsLoadingAction(true))
    const res = await getPageList(pageKey, params)
    // 这个if是处理删除后发的请求，假如最后一页删没了数据，应该重新请求前一页数据
    if (res.data.length === 0) {
      config.params.current--
      fetchPageListAction(config)
      return
    }
    dispatch(changePageListAction(res.data))
    dispatch(changeIsLoadingAction(false))
    // 保存当前参数状态，下一次刷新要用
    dispatch(changeSearchConfigAction(config))
    // 清除选中状态
    dispatch(changePropIdsAction([]))
    console.log('请求列表数据', res.data)
    return res.data
  }
)

// 单删
export const fetchPageDeleteAction = createAsyncThunk<
  void,
  number,
  IThunkState
>('page/delete', async (id, { getState, dispatch }) => {
  const config = getState().pageCommon.searchConfig
  const { pageKey } = config
  await reqPageDelete(pageKey, id)
  // 刷新列表数据
  dispatch(fetchPageListAction(config))
})

// 新增 / 编辑
export const fetchPageAddOrEditAction = createAsyncThunk<
  boolean,
  any,
  IThunkState
>(
  'page/add-edit',
  async ({ params, isAdd, isNeedEncrypt = true }, { getState, dispatch }) => {
    // 整理参数
    const config = getState().pageCommon.searchConfig
    const { pageKey } = config
    // 用户  要将参数加密再发请求，其他不用
    if (isNeedEncrypt) {
      const publicKey = getState().app.publicKey
      const encryptStr = encryptData(publicKey, params)
      const data = { encryptStr }
      if (encryptStr) {
        isAdd && (await reqPageAdd(pageKey, data))
        !isAdd && (await reqPageEdit(pageKey, data))
      }
    } else {
      isAdd && (await reqPageAdd(pageKey, params))
      !isAdd && (await reqPageEdit(pageKey, params))
      // 在新增或者编辑完成之后，假如当前是词库管理，还需要刷新过滤词库的配置
      pageKey === PagesKey.SensitiveLexIcon && (await reqRefreshLexicon())
    }
    // 刷新列表数据
    dispatch(fetchPageListAction(config))
    return true
  }
)

// 批量删除
export const fetchPageBatchDeleteAction = createAsyncThunk<
  void,
  number[],
  IThunkState
>('page/delete', async (ids, { getState, dispatch }) => {
  // 整理参数
  const config = getState().pageCommon.searchConfig
  const { pageKey } = config

  // 将参数加密再发请求
  const publicKey = getState().app.publicKey
  const encryptStr = encryptData(publicKey, { ids })
  if (encryptStr) await reqPageBatchDelete(pageKey, encryptStr)
  pageKey === PagesKey.SensitiveLexIcon && (await reqRefreshLexicon())
  // 刷新列表数据
  dispatch(fetchPageListAction(config))
})

const pageCommonSlice = createSlice({
  name: 'pageCommon',
  initialState,
  reducers: {
    changePageListAction(state, { payload }) {
      const { records, current = 1, total = 0, size = 10 } = payload
      // 正常是直接拿res.data.records数据，但是菜单页这些没有分页的直接拿的是payload
      state.pageList = records ?? payload
      state.pagination = { current, total, size }
    },
    changeIsLoadingAction(state, { payload }) {
      state.isLoading = payload
    },
    // 当前分页查询的参数
    changeSearchConfigAction(state, { payload }) {
      state.searchConfig.pageKey = payload.pageKey
      state.searchConfig.params = payload.params
    },
    // 当前页面选中id集合
    changePropIdsAction(state, { payload }) {
      state.propIds = payload
    },
    // 重置当前页数
    resetPaginationAction(state) {
      state.pagination = { current: 1, total: 0, size: 10 }
    },
    // 当前操作的行数据
    changeCurrentRecordAction(state, { payload }) {
      state.currentRecord = payload
    }
  }
})

export const {
  changePageListAction,
  changeIsLoadingAction,
  changeSearchConfigAction,
  changePropIdsAction,
  changeCurrentRecordAction
} = pageCommonSlice.actions
export default pageCommonSlice.reducer
